/**
 * @file test_macro_define.cpp
 * @brief 专门测试宏定义功能的测试用例
 * 验证新增的MacroDefine结构和相关解析能力
 */

#include "../moparse.h"
#include <iostream>
#include <fstream>
#include <chrono>
#include <functional>

class MacroDefineTestRunner {
public:
    MacroDefineTestRunner() : tests_passed_(0), tests_failed_(0) {}
    
    void run_test(const std::string& test_name, std::function<bool()> test_func) {
        std::cout << "运行宏定义测试: " << test_name << " ... ";
        auto start = std::chrono::high_resolution_clock::now();
        
        try {
            if (test_func()) {
                auto end = std::chrono::high_resolution_clock::now();
                auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
                std::cout << "通过 (" << duration.count() << "ms)" << std::endl;
                tests_passed_++;
            } else {
                std::cout << "失败" << std::endl;
                tests_failed_++;
            }
        } catch (const std::exception& e) {
            std::cout << "异常: " << e.what() << std::endl;
            tests_failed_++;
        }
    }
    
    void print_summary() {
        std::cout << "\n宏定义测试总结:" << std::endl;
        std::cout << "通过: " << tests_passed_ << std::endl;
        std::cout << "失败: " << tests_failed_ << std::endl;
        std::cout << "总计: " << (tests_passed_ + tests_failed_) << std::endl;
        
        if (tests_failed_ == 0) {
            std::cout << "\n🎉 所有宏定义测试都通过了！" << std::endl;
        } else {
            std::cout << "\n⚠️  有 " << tests_failed_ << " 个测试失败。" << std::endl;
        }
    }
    
    int get_failed_count() const { return tests_failed_; }

private:
    int tests_passed_;
    int tests_failed_;
};

// 创建各种宏定义测试文件
void create_macro_test_files() {
    
    // 1. 纯定义宏开关测试
    std::ofstream macro_switch("test_macro_switch.v");
    macro_switch << R"(
`define ENABLE_FEATURE
`define DEBUG_MODE
`define SIMULATION

module macro_switch_test (
    input clk,
    input reset,
`ifdef ENABLE_FEATURE
    input feature_enable,
    output feature_ready,
`endif
`ifdef DEBUG_MODE
    output [7:0] debug_data,
`endif
    output reg [7:0] data_out
);

`ifdef SIMULATION
    initial begin
        $display("Simulation mode enabled");
    end
`endif

endmodule
)";
    macro_switch.close();

    // 2. 有值纯净宏测试
    std::ofstream macro_value("test_macro_value.v");
    macro_value << R"(
`define DATA_WIDTH 16
`define ADDR_WIDTH 8
`define MAX_COUNT 255
`define MIN_COUNT 0

module macro_value_test (
    input clk,
    input reset,
    input [`DATA_WIDTH-1:0] data_in,
    input [`ADDR_WIDTH-1:0] addr_in,
    output reg [`DATA_WIDTH-1:0] data_out
);

parameter MAX = `MAX_COUNT;
parameter MIN = `MIN_COUNT;

reg [`DATA_WIDTH-1:0] memory [0:(1<<`ADDR_WIDTH)-1];

endmodule
)";
    macro_value.close();

    // 3. 有值表达式宏测试
    std::ofstream macro_expr("test_macro_expr.v");
    macro_expr << R"(
`define CALC_WIDTH(x) ((x)*2+1)
`define MUX_SEL(a,b,s) ((s) ? (a) : (b))
`define ADDR_RANGE(base, size) (base + size - 1)
`define BIT_MASK(width) ((1 << width) - 1)

module macro_expr_test (
    input clk,
    input reset,
    input [7:0] data_a,
    input [7:0] data_b,
    input select,
    output reg [`CALC_WIDTH(4)-1:0] result
);

localparam MASK = `BIT_MASK(8);
localparam END_ADDR = `ADDR_RANGE(16'h1000, 16'h0100);

always @(posedge clk) begin
    if (reset) begin
        result <= 0;
    end else begin
        result <= `MUX_SEL(data_a, data_b, select) & MASK;
    end
end

endmodule
)";
    macro_expr.close();

    // 4. 混合宏定义测试
    std::ofstream macro_mixed("test_macro_mixed.v");
    macro_mixed << R"(
// 开关宏
`define ENABLE_CACHE
`define ENABLE_DEBUG

// 值宏
`define CACHE_SIZE 1024
`define LINE_SIZE 32
`define DEBUG_LEVEL 2

// 表达式宏
`define CACHE_LINES(size, line) ((size)/(line))
`define LOG2(x) ($clog2(x))
`define IS_POWER_OF_2(x) (((x) & ((x)-1)) == 0)

module macro_mixed_test (
    input clk,
    input reset,
    input [31:0] addr,
    input [31:0] data_in,
    output [31:0] data_out
);

`ifdef ENABLE_CACHE
localparam LINES = `CACHE_LINES(`CACHE_SIZE, `LINE_SIZE);
localparam INDEX_WIDTH = `LOG2(LINES);

reg [31:0] cache_data [0:LINES-1];
reg [31:0] cache_tags [0:LINES-1];
reg cache_valid [0:LINES-1];

wire [INDEX_WIDTH-1:0] cache_index = addr[INDEX_WIDTH+1:2];
`endif

`ifdef ENABLE_DEBUG
wire debug_enable = (`DEBUG_LEVEL > 0);
wire [31:0] debug_info = {16'h0, addr[15:0]};
`endif

endmodule
)";
    macro_mixed.close();

    // 5. 包含错误宏定义的测试文件
    std::ofstream macro_error("test_macro_error.v");
    macro_error << R"(
// 正确的宏定义
`define VALID_MACRO 8

// 一些可能引起问题的宏定义
`define EMPTY_MACRO
`define RECURSIVE_MACRO `RECURSIVE_MACRO
`define UNDEFINED_REF `NONEXISTENT_MACRO

module macro_error_test (
    input clk,
    input [`VALID_MACRO-1:0] data
);

endmodule
)";
    macro_error.close();
}

// 清理宏定义测试文件
void cleanup_macro_test_files() {
    std::vector<std::string> files = {
        "test_macro_switch.v", "test_macro_value.v", "test_macro_expr.v",
        "test_macro_mixed.v", "test_macro_error.v",
        "macro_switch_test.modb", "macro_value_test.modb", "macro_expr_test.modb",
        "macro_mixed_test.modb", "macro_error_test.modb",
        "macro_reverse_test.v", "macro_instance_test.v"
    };
    
    for (const auto& file : files) {
        std::remove(file.c_str());
    }
}

// 测试纯定义宏开关（类型0）
bool test_macro_switch_type() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFile("test_macro_switch.v")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    
    // 检查模块解析
    if (db.modules_size() != 1) {
        return false;
    }
    
    // 检查宏定义数量
    if (db.macros_size() < 3) {
        std::cout << "宏定义数量不足: " << db.macros_size();
        return false;
    }
    
    // 检查特定宏定义
    bool found_enable = false;
    bool found_debug = false;
    bool found_simulation = false;
    
    for (const auto& macro : db.macros()) {
        if (macro.name() == "ENABLE_FEATURE" && macro.type() == 0) {
            found_enable = true;
        }
        if (macro.name() == "DEBUG_MODE" && macro.type() == 0) {
            found_debug = true;
        }
        if (macro.name() == "SIMULATION" && macro.type() == 0) {
            found_simulation = true;
        }
    }
    
    if (!found_enable || !found_debug || !found_simulation) {
        std::cout << "缺少预期的宏定义";
        return false;
    }
    
    std::cout << "解析出 " << db.macros_size() << " 个宏定义 ";
    return parser.saveToModb("macro_switch_test.modb");
}

// 测试有值纯净宏（类型1）
bool test_macro_value_type() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFile("test_macro_value.v")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    
    if (db.modules_size() != 1) {
        return false;
    }
    
    // 检查宏定义
    if (db.macros_size() < 4) {
        std::cout << "宏定义数量不足: " << db.macros_size();
        return false;
    }
    
    // 检查特定的值宏
    bool found_data_width = false;
    bool found_addr_width = false;
    
    for (const auto& macro : db.macros()) {
        if (macro.name() == "DATA_WIDTH" && macro.value() == "16" && macro.type() == 1) {
            found_data_width = true;
        }
        if (macro.name() == "ADDR_WIDTH" && macro.value() == "8" && macro.type() == 1) {
            found_addr_width = true;
        }
    }
    
    if (!found_data_width || !found_addr_width) {
        std::cout << "缺少预期的值宏定义";
        return false;
    }
    
    std::cout << "解析出 " << db.macros_size() << " 个宏定义 ";
    return parser.saveToModb("macro_value_test.modb");
}

// 测试有值表达式宏（类型2）
bool test_macro_expression_type() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFile("test_macro_expr.v")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    
    if (db.modules_size() != 1) {
        return false;
    }
    
    // 检查宏定义
    if (db.macros_size() < 4) {
        std::cout << "宏定义数量不足: " << db.macros_size();
        return false;
    }
    
    // 检查表达式宏
    bool found_calc_width = false;
    bool found_mux_sel = false;
    
    for (const auto& macro : db.macros()) {
        if (macro.name() == "CALC_WIDTH" && macro.type() == 2) {
            found_calc_width = true;
        }
        if (macro.name() == "MUX_SEL" && macro.type() == 2) {
            found_mux_sel = true;
        }
    }
    
    if (!found_calc_width || !found_mux_sel) {
        std::cout << "缺少预期的表达式宏定义";
        return false;
    }
    
    std::cout << "解析出 " << db.macros_size() << " 个宏定义 ";
    return parser.saveToModb("macro_expr_test.modb");
}

// 测试混合宏定义
bool test_macro_mixed_types() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFile("test_macro_mixed.v")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    
    if (db.modules_size() != 1) {
        return false;
    }
    
    // 检查宏定义数量和类型分布
    int type0_count = 0;  // 开关宏
    int type1_count = 0;  // 值宏
    int type2_count = 0;  // 表达式宏
    
    for (const auto& macro : db.macros()) {
        switch (macro.type()) {
            case 0: type0_count++; break;
            case 1: type1_count++; break;
            case 2: type2_count++; break;
        }
    }
    
    // 应该有所有三种类型的宏
    if (type0_count < 2 || type1_count < 3 || type2_count < 3) {
        std::cout << "宏类型分布异常: type0=" << type0_count 
                  << " type1=" << type1_count << " type2=" << type2_count;
        return false;
    }
    
    std::cout << "解析出 " << db.macros_size() << " 个宏定义 ";
    return parser.saveToModb("macro_mixed_test.modb");
}

// 测试宏定义的反向生成
bool test_macro_reverse_generation() {
    VerilogParser parser;
    
    // 解析包含宏定义的模块
    if (!parser.parseVerilogFile("test_macro_mixed.v")) {
        return false;
    }
    
    if (!parser.saveToModb("macro_mixed_test.modb")) {
        return false;
    }
    
    // 测试反向生成
    if (!parser.generateVerilog("macro_mixed_test.modb", "macro_mixed_test", "macro_reverse_test.v", "e")) {
        return false;
    }
    
    // 验证生成的文件
    std::ifstream gen_file("macro_reverse_test.v");
    if (!gen_file.is_open()) {
        return false;
    }
    
    std::string content;
    std::string line;
    while (std::getline(gen_file, line)) {
        content += line + "\n";
    }
    
    // 检查是否包含模块定义
    if (content.find("module macro_mixed_test") == std::string::npos) {
        return false;
    }
    
    std::cout << "生成文件大小: " << content.size() << " 字节 ";
    return true;
}

// 测试错误宏定义的处理
bool test_macro_error_handling() {
    VerilogParser parser;
    
    // 这个文件包含一些有问题的宏定义，但应该不会导致崩溃
    bool result = parser.parseVerilogFile("test_macro_error.v");
    
    if (result) {
        const auto& db = parser.getDatabase();
        std::cout << "解析出 " << db.macros_size() << " 个宏定义 ";
        
        // 应该至少解析出一个有效的宏
        if (db.macros_size() > 0) {
            return true;
        }
    }
    
    // 即使解析失败，只要不崩溃就算成功
    std::cout << "错误恢复正常 ";
    return true;
}

// 测试modb文件中宏定义的保存和加载
bool test_macro_save_load_cycle() {
    VerilogParser parser1, parser2;
    
    // 解析并保存
    if (!parser1.parseVerilogFile("test_macro_mixed.v")) {
        return false;
    }
    
    if (!parser1.saveToModb("macro_save_test.modb")) {
        return false;
    }
    
    // 加载到新的解析器
    if (!parser2.loadFromModb("macro_save_test.modb")) {
        return false;
    }
    
    const auto& db1 = parser1.getDatabase();
    const auto& db2 = parser2.getDatabase();
    
    // 验证宏定义数量一致
    if (db1.macros_size() != db2.macros_size()) {
        std::cout << "宏定义数量不一致: " << db1.macros_size() << " vs " << db2.macros_size();
        return false;
    }
    
    // 验证模块数量一致
    if (db1.modules_size() != db2.modules_size()) {
        std::cout << "模块数量不一致";
        return false;
    }
    
    std::cout << "保存/加载 " << db1.macros_size() << " 个宏定义 ";
    std::remove("macro_save_test.modb");
    return true;
}

// 性能测试：大量宏定义
bool test_macro_performance() {
    // 创建包含大量宏定义的文件
    std::ofstream large_macro("test_large_macro.v");
    large_macro << "// 大量宏定义性能测试\n";
    
    // 生成100个宏定义
    for (int i = 0; i < 100; i++) {
        large_macro << "`define MACRO_" << i << " " << i << "\n";
    }
    
    large_macro << R"(
module large_macro_test (
    input clk,
    input reset,
    output reg [31:0] data
);

// 使用一些宏定义
parameter P0 = `MACRO_0;
parameter P50 = `MACRO_50;
parameter P99 = `MACRO_99;

endmodule
)";
    large_macro.close();
    
    auto start = std::chrono::high_resolution_clock::now();
    
    VerilogParser parser;
    bool result = parser.parseVerilogFile("test_large_macro.v");
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    if (result) {
        const auto& db = parser.getDatabase();
        std::cout << "解析 " << db.macros_size() << " 个宏定义，耗时 " << duration.count() << "ms ";
    }
    
    std::remove("test_large_macro.v");
    return result && duration.count() < 1000; // 应该在1秒内完成
}

int main() {
    std::cout << "开始宏定义功能专项测试...\n" << std::endl;
    
    // 创建测试文件
    create_macro_test_files();
    
    MacroDefineTestRunner runner;
    
    // 运行宏定义测试
    runner.run_test("纯定义宏开关(type 0)", test_macro_switch_type);
    runner.run_test("有值纯净宏(type 1)", test_macro_value_type);
    runner.run_test("有值表达式宏(type 2)", test_macro_expression_type);
    runner.run_test("混合宏定义类型", test_macro_mixed_types);
    runner.run_test("宏定义反向生成", test_macro_reverse_generation);
    runner.run_test("错误宏定义处理", test_macro_error_handling);
    runner.run_test("宏定义保存加载", test_macro_save_load_cycle);
    runner.run_test("大量宏定义性能", test_macro_performance);
    
    // 清理测试文件
    cleanup_macro_test_files();
    
    // 输出测试结果
    runner.print_summary();
    
    return runner.get_failed_count() > 0 ? 1 : 0;
}